package com.woniu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.mapper.AddressMapper;
import com.woniu.mapper.ChinaMapper;
import com.woniu.pojo.Address;
import com.woniu.pojo.China;
import com.woniu.redis.RedisConst;
import com.woniu.service.AddressService;
import com.woniu.service.ChinaService;
import com.woniu.vo.AddressRequest;
import com.woniu.vo.AddressVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address>
    implements AddressService  {
    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ChinaMapper chinaMapper;

    @Autowired
    private ChinaService chinaService;

    /**
     * 通过 userId 查询当前用户地址列表
     *
     * */
    @Override
    public List<AddressVo> findAddressByUserId(Long userId) {
        // 地址表 userId = 当前登录用户id
        LambdaQueryWrapper<Address> wrapper = new LambdaQueryWrapper<Address>()
                .eq(Address::getUserId, userId);
        // 查询当前用户地址列表
        List<Address> addressList = addressMapper.selectList(wrapper);
        // 将 addressList 转为 addressVoList
        List<AddressVo> addressVoList = addressList.stream().map(
                address -> {
                    //省+市+区+详细地址  label 地址详情，需要拼接
                    String label = address.getProvince() + address.getCity() + address.getArea() + address.getDetailAddress();
                    return new AddressVo(address.getId(), label, address.getIsDefault());
                }
        ).collect(Collectors.toList());

        return addressVoList;
    }

    /**
     * 查询所有省份
     * */
    @Override
    public List<China> getAllProvinces() {
        // 先判断缓存中是否 有 省份信息
        if (! redisTemplate.hasKey(RedisConst.PROVINCES)) {
            // 如果缓存 没有省份信息，查询数据库
            LambdaQueryWrapper<China> wrapper = new LambdaQueryWrapper<China>()
                    .eq(China::getPid, 0)
                    .ne(China::getId, 0)    // 排除掉id为0的数据。 查询结果存在中国，需要将其排除
                    .orderByAsc(China::getId);
            List<China> provincesList = chinaMapper.selectList(wrapper);

            // 将查询省份 放入redis。通过zset集合存储，id是分数
            list().forEach(province ->
                    redisTemplate.opsForZSet().add(RedisConst.PROVINCES, province, province.getId())
            );
            return provincesList;
        }

        // 从redis获取所有元素
        Set<China> set = redisTemplate.opsForZSet().range(RedisConst.PROVINCES, 0, -1);
        return new ArrayList<>(set);
    }

    @Override
    @Cacheable(cacheNames = RedisConst.CITIES,key = "#root.methodName + #provinceId")
    public List<China> getAllCities(Integer provinceId) {
        List<China> list = chinaService.list(Wrappers.lambdaQuery(China.class)
                .eq(Objects.nonNull(provinceId), China::getPid, provinceId) // 判断是否为空, 不为空则根据省份id查询
        );
        return list;
    }

    /**
     * 保存用户地址
     *
     * */
    @Override
    @Transactional
    public void saveAddress(AddressRequest addressRequest, Long userId) {
        // 根据省份id，获取省份名称
        China province = chinaService.findById(addressRequest.getProvince());
        // 根据城市 id，获取城市名称
        China city = chinaService.findById(addressRequest.getCity());
        // 根据区县 id，获取区县名称.这个地方需要做空指针处理
        China area = null;
        if (addressRequest.getDistrict() == null) {
//            China area = chinaService.findById(addressRequest.getDistrict()); 查询操作直接不需要了
        } else {
            area = chinaService.findById(addressRequest.getDistrict());
        }

        log.info("area:{}",addressRequest.getDistrict());
        // 封装地址信息
        Address address = new Address();

        // 拷贝属性
        BeanUtils.copyProperties(addressRequest, address);

        // 设置 address独有属性
        address.setProvince(province.getName());
        address.setCity(city.getName());
        if (area == null) {
            address.setArea(null);
        } else {
            address.setArea(area.getName());
        }
        address.setStatus("1");
        address.setTelephone(addressRequest.getTel());
        address.setUserId(userId);

        // 判断是否为默认地址, 将 本地地址 的 isDefault == 1，并且设置该用户其他地址  isDefault == 0
        if (address.getIsDefault() == 1) {
            // 将改用所有地址 设置为 0 .此处需要开启事务
            LambdaUpdateWrapper<Address> wrapper = new LambdaUpdateWrapper<Address>()
                    .set(Address::getIsDefault, 0)
                    .eq(Address::getUserId, userId);
            addressMapper.update(null, wrapper);

            // 将本地治设置为 1
            LambdaUpdateWrapper<Address> eq = new LambdaUpdateWrapper<Address>()
                    .set(Address::getIsDefault, 1)
                    .eq(Address::getId, address.getId())
                    .eq(Address::getUserId, userId);
            addressMapper.update(null, eq);
        }

        // 添加地址
        addressMapper.insert(address);
    }

}
